package me.alex.learnkotlin.learnKT4

import java.util.*
import kotlin.collections.HashMap
import kotlin.concurrent.thread

/**
 * 学习 Lambda编程
 */
fun main() {
    //1.0 集合
    //初始化 使用listOf
    val list1 = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
    for (fruit in list1) {
        println(fruit)
    }

    //可变的val集合 使用mutableListOf关键字
    val list2 = mutableListOf("Apple", "Banana", "Orange", "Pear", "Grape")
    list2.add("Watermelon")
    for (s in list2) {
        println(s)
    }

    //1.1 set集合
    //初始化 Set集合底层使用hash机制存放数据,无法保证有序
    val set1 = setOf("Apple", "Banana", "Orange", "Pear", "Grape")
    for (s in set1) {
        println(s)
    }

    //可变初始化
    val set2 = mutableSetOf("Apple", "Banana", "Orange", "Pear", "Grape")
    set2.add("Watermelon")


    //1.2 Map
    //普通写法
    val map1 = HashMap<String, Int>()
    map1.put("Apple", 1)

    //推荐写法
    map1["Banana"] = 2
    map1["Orange"] = 3
    map1["Pear"] = 4
    map1["Grape"] = 5

    //读取数据
    val number = map1["Apple"]

    //Kotlin写法
    val map2 = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
    //这里for循环同时声明2个变量 默认对应是key,value
    for ((fruit, num) in map2) {
        println("name is $fruit , num = $num")
    }


    //1.3 集合的函数式API
    //maxBy函数被不推荐使用 新版本请使用maxByOrNull
    val list3 = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val maxLengthFruit = list3.maxByOrNull { it.length }
    println("max length fruit is $maxLengthFruit")

    /*
    Lambda表达式的语法结构:
    {参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
     */
    //分解写法
    val list4 = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val lambda = { fruit: String -> fruit.length }
    val maxLength = list4.maxByOrNull(lambda)
    //简化
    val maxLength1 = list4.maxByOrNull({ fruit: String -> fruit.length })
    //简化2 可以去掉括号
    val maxLength2 = list4.maxByOrNull { fruit: String -> fruit.length }
    //简化3 Kotlin可以自动推导类型,可以去掉参数类型
    val maxLength3 = list4.maxByOrNull { fruit -> fruit.length }
    //简化4 如果Lambda只有一个参数,可以不声明参数名 用it代替
    val maxLength4 = list4.maxByOrNull { it.length }

    //map函数
    /**
     * 将字母都转化为大写
     * map函数很强大 可以做各种转换方式 这里我理解和rxJava中的map函数类似的作用
     */
    val list5 = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
    val newList = list5.map { it.toUpperCase(Locale.ROOT) }
    for (s in newList) {
        println(s)
    }

    //filter函数 过滤
    //先过滤名字长度小于等于5 再把过滤好的数据都转化成大写字母
    //这里filter和map函数虽然先后顺序不影响结果 但是经过filter过滤,map再转化需要操作的次数就减少了可以提升效率
    val newList1 = list5.filter { it.length <= 5 }.map { it.toUpperCase(Locale.ROOT) }

    //any和all函数 判断集合中所有元素是否都满足条件
    val anyResult = list5.any { it.length <= 5 }
    val allResult = list5.all { it.length <= 5 }
    println("anyResult = $anyResult ,  allResult = $allResult")


    //1.4 Java函数式API
    /**
     * java中的写法
     * new Thread(new Runnable(){
     *      @Override
     *      public void run(){
     *          System.out.println("Thread is run");
     *      }
     * }).start();
     */
    //Kotlin写法
    thread {
        Runnable { "Thread is run" }
    }.start()
}